### --- 6、3 遍历字典
from test12 import favorite_languages

# 一个Python 字典可能包含几个键值对，也可能包含数百万个键值对
# 鉴于字典可能包含大量数据，Python支持对字典进行遍历。
# 字典可用于以各种方式存储信息，因此有多种遍历方式：既可以遍历字典的所有键值对，也可只遍历键或值

# 6.3.1 遍历所有的键值对
# 在探索各种遍历方法前，先来看一个新字典

user_0 = {'username': 'efermi',
          'first': 'enrico',
          'last': 'fermi',
          }

# 如何获悉该用户字典中的所有信息？ ———— 使用for循环
for key, value in user_0.items():
    print(f"\nKey: {key}")
    print(f"\nValue: {value}")

# 要编写遍历字典的for循环，可声明两个变量，分别用于存储键值对中的键和值。
# 这两个变量可以使用任意名称
# for语句的第二部分包含字典名和方法 .items()   这个方法返回一个键值对列表。
# 接下来，for循环依次将每个键值对赋给指定的两个变量。
# 在这个示例中，使用这两个变量来打印每个键和与他关联的值。
# 第一个函数调用print() 中的 “\n” 确保在输出每个键值对前插入一个空行

# 在6.2.6中的favorite_languages 中，字典存储的是不同人的同一种信息，对此类的字典，遍历所有的键值对很合适

favorite_languages = {'jen': 'python',
                      'sarah': 'c',
                      'edward': 'rust',
                      'phil': 'python',
                      }
for name, language in favorite_languages.items():
    print(f"{name.title()}'s favorite language is {language.title()}")


# 6.3.2 遍历字典中的所有键
# 在不需要使用字典中的值时 .keys() 方法很好用

print("\n\n")

for name in favorite_languages.keys():
    print(name.title())

# 这个for循环让Python提取字典中的所有键，并依次将他们赋给变量 name
# 如果不加 .key()  输出不变，但是加了更好让人理解你是在遍历所有键

# 在着种循环中，可使用当前的键来访问与之相关联的值。
# 下面来打印两条消息，指出两个朋友喜欢的编程语言
# 在名字为指定的朋友的名字时，打印一条消息

favorite_languages = {'jen': 'python',
                      'sarah': 'c',
                      'edward': 'rust',
                      'phil': 'python',
                      }
friends = {'phil', 'sarah'}

for name in favorite_languages.keys():
    print(f"Hi {name.title()}!")
    if name in friends:
        language = favorite_languages[name].title()
        print(f"\t{name.title()}, I see you love {language}!")
        # \t 代表空四个格，相当于按了一个 Tab 键

# 还可以用keys() 确定某个人是否接受了调查。

if 'erin' not in favorite_languages.keys():
    print("Erin, please take you poll!")

# keys() 方法并非只能用于遍历： 实际上，他会返回一个列表，其中包含字典中的所有键
# 因此if 语句会核实 ‘erin’，是否在这个列表中

# 6.3.3 按特定的顺序遍历字典中的所有键

# 遍历字典时将按插入元素的顺序返回其中的元素
# 但是在一些情况下，你可能要按于此不同的顺序遍历字典
# 要以特定的顺序返回元素，一种办法是在 for 循环中对返回的键进行排序。
# 为此使用 sorted() 函数来获得按特定顺序排列的键的列表的副本：

for name in sorted(favorite_languages.keys()):
    print(f"{name.title()}, thank you for taking the poll.")
# 这条for语句类似于其他for语句，但对方法 dictionary.keys() 的结果调用了 sorted() 函数
# 这会让Python获取字典中的所有键，并在遍历前对这个列表进行排序。
# 输出表明，按字母顺序显示了所有被调查者的名字

# 6.3.4 遍历字典中的所有值

# 如果你感兴趣的是字典包含的值，可使用 .values() 方法
# 它会返回一个值 列表，不包含任何键

print("\n\n")
print("The following languages have been mentioned:")
for language in favorite_languages.values():
    print(language.title())

# 但是这种做法提取字典中的所有值，而没有考虑值是否有重复。
# 当涉及很少值时，这也许不是问题，担当数据很多，最终的值列表可能包含很多重复的项
# 为剔除重复项，可以使用  set()  函数
# 集合中的每个元素都是独一无二的

print("\n")

print("The following languages have ;been mentioned:")
for language in set(favorite_languages.values()):
    print(language.title())

# 通过将 值列表 传入set() 可让Python找出列表中独一无二的元素，并使用这些元素来创建一个集合

print("\n")
### 注意
#   可以直接使用 花括号来创建集合，打印集合时，不会打印其中的重复的元素


# 列表
language1 = ['zhong wen', 'ying wen', 'de wen', 'ying wen']
for language in language1:
    print(language)

# 字典
language2 = {'zhong wen': 'ni hao',
             'ying wen': 'hello',
             'de wen': 'bu zhi dao za shuo'}
for name, language in language2.items():
    print(f"{name}喜欢的语言是{language}")

# 集合
language3 = {'zhong wen', 'ying wen', 'de wen', 'ying wen'}
# 集合可以直接打印
print(language3)  # 打印结果是 {'zhong wen', 'ying wen', 'de wen'}

print("\n\n")

### -------- 6、4 嵌套

# 有时候，需要将多个字典存储在列表中或将列表作为值存储在字典中，这称为嵌套
# 可以在列表中嵌套字典，在字典中嵌套列表，甚至在字典中嵌套字典。
# 嵌套是一个强大的功能

# 6.4.1 字典列表

# 字典alien_0 包含一个外星人的各种信息，但无法存储第二个外星人的信息，更别说屏幕上全部外星人的信息了。
# 如何管理成群结对的外星人呢？ 一种办法是创建一个外星人列表，其中每个外星人都是一个字典

alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}

aliens = [alien_0, alien_1, alien_2]

for alien in aliens:
    print(alien)

# 更符合显示的情形是，外星人不止三个，而且每个外星人都是代码自动生成的。
# 在下面的示例中，使用range() 生成了 30 个外星人

# 创建一个用于存储外星人的空列表
aliens = []

# 创建30 个绿色的外星人
for alien_number in range(30):   # range() 函数返回一个数字序列，告诉Python要重复这个循环多少次。
    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
    aliens.append(new_alien)  # .append 方法----- 在列表末尾添加新元素

# 显示前5个外星人
for alien in aliens[:5]:
    print(alien)
print('...')

# 显示创建了多少个外星人
print(f"Total number of aliens: {len(aliens)}")

# 这些外星人都具有相同的特征，但在Python 看来，每个外星人都是独立的，这让我们能够独立地修改这些外星人

# 在什么情况下需要处理成群结队地外星人呢？ 想象以西，随着游地进行，有些外星人会变色且加快移动素的
# 在必要时可使用for 循环和if语句来修改某些外星人地颜色
# 例如，要将前三个外星人修改为黄色、速度中等且值为10 分

for alien in aliens[:3]:
    if alien['color'] == 'green':
        alien['color'] = 'yellow'
        alien['speed'] = 'medium'
        alien['points'] = 10

# 显示前5个外星人

for alien in aliens[:5]:
    print(alien)
print("...")

# 鉴于要修改前三个外星人，我们遍历一个只包含这些外星人地切片。
# 当前，所有外星人都是绿色的，但情况并非如此，因此可以编写一条if 语句来确保只修改绿色外星人
# 如果外星人是绿色的，就将其颜色改为 yellow 等

# 6.4.2 在字典中存储列表
# 有时候，需要将列表存储在字典中，而不是将字典存储在列表中。
# 例如：如何描述顾客点地比萨呢？ 如果使用列表，只能存储要添加的比萨配料，但如果使用字典，其中的配料列表就是是用来描述比萨的一个方面

# 在下面的示例中，存储了比萨两个方面的信息：外皮类型和配料列表。
# 配料列表是一个与键 ‘toppings’ 关联的值. 要访问该列表，我们使用字典名和键 ‘toppings’ 就像访问字典中的其他值一样
# 这将返回一个 配料列表，而不是单个值：

# 存储顾客所点的比萨的信息
pizza = {'crust': 'thick',
         'toppings': ['mushrooms', 'extra cheese'],
         }
# 概述顾客点的比萨
print(f"You ordered a {pizza['crust']}-crust pizza "
    "with the following toppings:")

print(f"You ordered a {pizza['crust']}-crust pizza "
      f"with the following toppings:") # print() 括号中的内容换行了，必须要另加双引号

for topping in pizza['toppings']:
    print(f"\t{topping}")

# 每当需要在字典中将一个键关联到多个值时，都可以在字典中嵌套一个列表。
# 在本章前面有关喜欢的编程语言的示例中，如果将每个人的回答都存储在一个列表中，被调查者就可以选择多种喜欢的语言
# 在这种情况下，当我们遍历字典时，与每个被调查者关联的都是一个语言列表，而不是一种语言。
# 因此，在遍历该字典的for 循环中，需要再使用一个for 循环来遍历与被调查者关联的语言列表：

favorite_languages = {'jen': ['python', 'rust'],
                      'sarah': ['c'],
                      'edward': ['rust', 'go'],
                      'phil': ['python', 'haskell'],
                      }

for name, languages in favorite_languages.items():   # 第一次循环，对象时字典中的 键和 值列表
    print(f"\n{name.title()}'s favorite languages are:")
    for language in languages:                       # 由于值列表的存在，要在使用一个循环，遍历值列表
        print(f"\t{language.title()}")


# 列表和字典的嵌套层级不应过多。如果嵌套层级比前面的示例多得多，很可能有更简单的解决方案

# 6.4.3 在字典中存储字典
# 可以在字典中嵌套字典，但这样可能会让代码很快变得非常复杂。

# 如果有一个网站有多个用户，每个用户都有独特的用户名，可在字典中将用户名作为键，然后将每个用户的信息存储在一个字典中
# 并将该字典作为与用户名关联的值。
# 在下面的程序中，存储每个用户的三项信息：名、性和居住地。
# 为访问这些信息，我们遍历所有的用户名，并访问与每个用户关联的信息字典：

users = {'aeinstein': {'first': 'albert', 'last': 'einstein', 'location': 'princeton',},
         'mcurie':    {'first': 'marie', 'last': 'curie', 'location': 'paris'},
         }
for username, user_info in users.items():
    print(f"\nUsername: {username}")
    full_name = f"{user_info['first']} {user_info['last']}"
    location = user_info['location']

    print(f"\tFull name: {full_name.title()}")
    print(f"\tLocation: {location.title()}")

# 首先定义一个名为 users 的字典，其中包含两个键： 用户名‘aeinstein’ 和 ‘mcurie’。
# 与每个键关联的值都是一个字典，其中包含用户的名、性和居住地。
# 然后，遍历字典 users， 让Python 依次将每个键赋给变量 username，并依次将与当前键相关联的字典赋给变量 user_info
# 在循环内部，将用户名打印出来了
# 接下来，开始访问内部的字典。 变量user_info 包含用户信息字典，而该字典包含三个键： ‘first’、 ‘last’ 和 ‘location’
# 对于每个用户，都是用这些键来生成整洁的姓名和居住地，然后打印有关用户的简要信息














































































































